package cn.com.cifi.mars.service.impl;

import cn.com.cifi.mars.bean.vo.PageResult;
import cn.com.cifi.mars.bean.vo.signPlan.SignPlanProgressVo;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.*;
import cn.com.cifi.mars.entity.*;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.*;
import cn.com.cifi.mars.service.*;
import cn.com.cifi.mars.util.ListUtils;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.VersionNameUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: jyx
 * @date: 2020/7/27 9:36
 */
@Slf4j
@Service
public class SignPlanProgressServiceImpl extends ServiceImpl<SignPlanProgressMapper, SignPlanProgress> implements SignPlanProgressService {

    @Autowired
    private SignPlanProgressMapper signPlanProgressMapper;
    @Autowired
    private SignPlanVersionService signPlanVersionService;
    @Autowired
    private SupplyPlanVersionService supplyPlanVersionService;
    @Autowired
    private ApprovedRecoreViewService approvedRecoreViewService;
    @Autowired
    private SignPlanVersionMapper signPlanVersionMapper;
    @Autowired
    private IdmUserService idmUserService;
    @Autowired
    private ApprovalBillMapper approvalBillMapper;
    @Autowired
    private SignPlanApprovedMapper signPlanApprovedMapper;
    @Autowired
    private StageService stageService;

    int SALE_ROOM_UPDATE_SIZE = 1000;

    /**
     * 签约计划进度底表
     * @param yearMonth
     */
    @Transactional
    @Override
    public void refresh(String yearMonth) {
        //1、获取底表数据
        List<SignPlanProgress> allList = new ArrayList<>();

        //获取事业部、城市公司、项目、分期全部层级结构数据
        List<SignPlanProgress> hrOrgTypeList = signPlanProgressMapper.selectAllOrgType(HrOrgTypeEunm.ORG_32.getKey());
        //获取全部项目id列表
        List<String> projectIdList = hrOrgTypeList.stream().map(s -> s.getProjectId()).distinct().collect(Collectors.toList());
        //获取指定月份签约版本数据
        List<SignPlanVersion> signPlanVersionList = signPlanVersionMapper.selectLatestVersionByAffiliationMonth(yearMonth);

        //归属年月
        hrOrgTypeList.forEach(s->s.setSnapshootYearMonth(yearMonth));


        for(String projectId : projectIdList){
            List<SignPlanProgress> stageProgressList = hrOrgTypeList.stream().filter(s -> s.getProjectId().equals(projectId)).collect(Collectors.toList());

            //筛选项目下的签约版本
            List<SignPlanVersion> projectVersionList = signPlanVersionList.stream().filter(s -> s.getProjectId().equals( projectId)).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(projectVersionList)){
                for (SignPlanProgress stageProgress : stageProgressList){
                    //剔除分期
                    MdmStage mdmStage = stageService.selectById(stageProgress.getStageId());
                    if(StageStatusEnum.INACTIVE.getKey().equals(mdmStage.getStatus())){
                        //剔除禁用分期
                        continue;
                    }
                    if(!signPlanVersionService.getStageIsSaly(stageProgress.getStageId())){
                        //剔除全盘最新供货版本未全部可租或不可租售的分期
                        continue;
                    }
                    stageProgress.setSignVersionName("无");
                    stageProgress.setVersionState(VersionStatusEnum.NOTCREATE.getKey());
                    stageProgress.setVersionStateName("未编制");
                    allList.add(stageProgress);
                }
                continue;
            }

            //获取项目年度签约目标金额、上一个审批单年度签约目标金额、差异金额
            Map<String, BigDecimal> targetMap = getYearSignTargetAmount(projectVersionList,stageProgressList, projectId, yearMonth);

            project:
            for (SignPlanProgress stageProgress : stageProgressList){
                //剔除分期
                MdmStage mdmStage = stageService.selectById(stageProgress.getStageId());
                if(StageStatusEnum.INACTIVE.getKey().equals(mdmStage.getStatus())){
                    //剔除禁用分期
                    continue;
                }
                if(!signPlanVersionService.getStageIsSaly(stageProgress.getStageId())){
                    //剔除全盘最新供货版本未全部可租或不可租售的分期
                    continue;
                }

                //筛选分期下的签约版本(每个分期下只存一个版本)
                List<SignPlanVersion> stageVersionList = signPlanVersionList.stream().filter(s -> s.getProjectfId().equals( stageProgress.getStageId())).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(stageVersionList)) {
                    stageProgress.setSignVersionName("无");
                    stageProgress.setVersionState(VersionStatusEnum.NOTCREATE.getKey());
                    stageProgress.setVersionStateName("未编制");
                    allList.add(stageProgress);
                    continue;
                }

                for(SignPlanVersion signPlanVersion : stageVersionList){
                    SignPlanProgress progress = new SignPlanProgress();
                    BeanUtils.copyProperties(stageProgress,progress);
                    //签约版本id
                    String signPlanId = signPlanVersion.getId();
                    //来源供货版本id
                    String sourceSupplyId = signPlanVersion.getSourceSupplyId();
                    //创建账户
                    String createBy = signPlanVersion.getCreateBy();

                    //供货版本数据
                    SupplyPlanVersion supplyPlanVersion = supplyPlanVersionService.getById(sourceSupplyId);
                    if(null == supplyPlanVersion || supplyPlanVersion.getIsDelete() == 1){
                        break project;
                    }
                    //审批单数据
                    if(VersionStatusEnum.SUCCESSAPPROVED.getKey().equals(signPlanVersion.getVersionState())){
                        ApprovalBill approvalBill = approvedRecoreViewService.selectBillByVersionId(signPlanId);
                        if(null != approvalBill){
                            //审批通过时间
                            progress.setSuccessApprovalTime(approvalBill.getUpdateTime());
                        }
                    }
                    //用户数据
                    IdmUser user = idmUserService.getByAlias(createBy);
                    if(user == null){
                        progress.setCreateByName("系统");
                    }else {
                    	progress.setCreateByName(user.getUsercn());
                    }
                    //签约版本名称
                    String signVersionName = VersionNameUtils.getVersionName(signPlanVersion);
                    //供货版本名称
                    String supplyVersionName = VersionNameUtils.getVersionName(supplyPlanVersion);
                    //创建时间
                    LocalDateTime createTime = signPlanVersion.getCreateTime();
                    //创建方式
                    String versionCreate = signPlanVersion.getVersionCreate();
                    //创建方式名称
                    String versionCreateName = VersionCreateEnum.getKeyByValue(versionCreate);
                    //版本状态
                    String versionState = signPlanVersion.getVersionState();
                    //版本状态名称
                    String versionStateName = VersionStatusEnum.getValueByKey(versionState);
                    //年度签约目标金额
                    BigDecimal yearSigningTargetAmount = targetMap.get("yearSignTargetAmount");
                    //上个审批单年度签约目标
                    BigDecimal lastYearSigningTargetAmount = targetMap.get("lastYearSigningTargetAmount");
                    //差异金额
                    BigDecimal differenceAmount = targetMap.get("differenceAmount");

                    progress.setSignPlanId(signPlanId);
                    progress.setSourceSupplyVersionId(sourceSupplyId);
                    progress.setSignVersionName(signVersionName);
                    progress.setSoureSupplyVersionName(supplyVersionName);
                    progress.setCreateBy(createBy);
                    progress.setCreateTime(createTime);
                    progress.setVersionCreate(versionCreate);
                    progress.setVersionCreateName(versionCreateName);
                    progress.setVersionState(versionState);
                    progress.setVersionStateName(versionStateName);
                    progress.setYearSignTargetAmount(yearSigningTargetAmount);
                    progress.setLastYearSignTargetAmount(lastYearSigningTargetAmount);
                    progress.setDifferenceAmount(differenceAmount);
                    allList.add(progress);
                }
            }
        }

        //2、删除底表
        signPlanProgressMapper.delByYearMonth(yearMonth);

        //3、写入底表
        if(CollectionUtils.isNotEmpty(allList)){
            //批量插入一次1000条
            List<List> subList = ListUtils.getSubList(allList, SALE_ROOM_UPDATE_SIZE);
            for (List list : subList) {
                List<SignPlanProgress> insertList = (List<SignPlanProgress>) list;
                signPlanProgressMapper.insertList(insertList);
            }
        }
    }

    /**
     * 获取签约进度表数据
     * @param yearMonth
     * @param projectIdList
     * @return
     */
    @Override
    public List<SignPlanProgress> getSignPlanProgress(String yearMonth, List<String> projectIdList) {
        QueryWrapper<SignPlanProgress> queryWrapper = new QueryWrapper();
        queryWrapper.eq("snapshoot_year_month",yearMonth).in("project_id",projectIdList);

        List<SignPlanProgress> signPlanProgressList = signPlanProgressMapper.selectList(queryWrapper);
        return signPlanProgressList;
    }

    /**
     * 获取签约进度表数据
     * @param yearMonth 指定年月
     * @param projectIdList 权限项目列表
     * @param name 模糊搜索字段(区域名称、城市名称、项目名称)
     * @param startTime 起始时间
     * @param endTime 结束时间
     * @return
     */
    @Override
    public List<SignPlanProgressVo> getSignPlanProgressVo(String yearMonth, List<String> projectIdList, String name,String versionStatus, String startTime, String endTime) {
        List<SignPlanProgressVo> voList = new ArrayList<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss");

        QueryWrapper<SignPlanProgress> queryWrapper = new QueryWrapper();
        queryWrapper.eq("snapshoot_year_month",yearMonth)
                .eq(StringUtils.isNotEmpty(versionStatus),"version_state",versionStatus)
                .in("project_id",projectIdList)
                .ge(StringUtils.isNotEmpty(startTime),"success_approval_time",StringUtils.isNotEmpty(startTime)?LocalDateTime.parse(startTime, df):startTime)
                .le(StringUtils.isNotEmpty(endTime),"success_approval_time",StringUtils.isNotEmpty(endTime)?LocalDateTime.parse(endTime, df):endTime)
                .and(StringUtils.isNotEmpty(name),
                        s-> s.like("business_division_name",name)
                            .or()
                            .like("city_company_name",name)
                            .or()
                            .like("project_name",name)
                );

        List<SignPlanProgress> signPlanProgressList = signPlanProgressMapper.selectList(queryWrapper);
        signPlanProgressList.forEach(t->{
            SignPlanProgressVo vo = new SignPlanProgressVo();
            BeanUtils.copyProperties(t,vo);
            voList.add(vo);
        });
        return voList;
    }

    /**
     * 获取签约进度表分页数据
     * @param current 页码
     * @param pageSize 条数
     * @param yearMonth 指定年月
     * @param projectIdList 权限项目列表
     * @param name 模糊搜索字段(区域名称、城市名称、项目名称)
     * @param versionStatus 版本状态
     * @param startTime 起始时间
     * @param endTime 结束时间
     * @return
     */
    @Override
    public PageResult getSignPlanProgressPage(String current, String pageSize, String yearMonth, List<String> projectIdList, String name, String versionStatus, String startTime, String endTime) {
        PageResult pageResult = new PageResult();
        List<SignPlanProgressVo> voList = new ArrayList<>();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss");

        QueryWrapper<SignPlanProgress> queryWrapper = new QueryWrapper();
        queryWrapper.eq("snapshoot_year_month",yearMonth)
                .eq(StringUtils.isNotEmpty(versionStatus),"version_state",versionStatus)
                .in("project_id",projectIdList)
                .ge(StringUtils.isNotEmpty(startTime),"success_approval_time",LocalDateTime.parse(startTime, df))
                .le(StringUtils.isNotEmpty(endTime),"success_approval_time",LocalDateTime.parse(endTime, df))
                .and(StringUtils.isNotEmpty(name),
                        s-> s.like("business_division_name",name)
                                .or()
                                .like("city_company_name",name)
                                .or()
                                .like("project_name",name)
                );
        Page page = new Page();
        page.setCurrent(Long.valueOf(current));
        page.setSize(Long.valueOf(pageSize));
        IPage dataPage = signPlanProgressMapper.selectPage(page, queryWrapper);

        List<SignPlanProgress> signPlanProgressList = dataPage.getRecords();
        signPlanProgressList.forEach(t->{
            SignPlanProgressVo vo = new SignPlanProgressVo();
            BeanUtils.copyProperties(t,vo);
            voList.add(vo);
        });

        pageResult.setCurrent(dataPage.getCurrent());
        pageResult.setPageSize(dataPage.getSize());
        pageResult.setTotal(dataPage.getTotal());
        pageResult.setList(voList);
        return pageResult;
    }


    /**
     * 获取项目年度签约目标金额、上一个审批单年度签约目标金额、差异金额
     * @param signPlanVersionList
     * @param stageProgressList
     * @param projectId
     * @param yearMonth
     * @return
     */
    private Map<String,BigDecimal> getYearSignTargetAmount(List<SignPlanVersion> signPlanVersionList, List<SignPlanProgress> stageProgressList, String projectId, String yearMonth) {
        HashMap map = new HashMap();
        //全盘签约id列表
        List<String> overallVersionIdList = new ArrayList<>();
        //当前年度签约目标
        BigDecimal yearSignTargetAmount;
        //上个审批单年度签约目标
        BigDecimal lastYearSigningTargetAmount;
        //差异金额
        BigDecimal differenceAmount;

        //版本列表中是否存在没有审批单的版本
        boolean isNotApproved = isNotApproved(signPlanVersionList);
        if(isNotApproved){
            //不存在在途版本点的分期,取全盘最新的版本
            for (SignPlanProgress signPlanProgress : stageProgressList){
                List<SignPlanVersion> signPlanVersion = signPlanVersionList.stream().filter(s -> s.getProjectfId().equals(signPlanProgress.getStageId())).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(signPlanVersion)){
                    overallVersionIdList.add(signPlanVersion.get(0).getId());
                }else{
                    SignPlanVersion version = getOverallByProjectf(signPlanProgress.getStageId());
                    if(null == version){
                        continue;
                    }else {
                        overallVersionIdList.add(version.getId());
                    }
                }
            }
            yearSignTargetAmount = signPlanVersionService.getYearSignTarget(overallVersionIdList, yearMonth, 1);
            //上个审批单
            ApprovalBill approvalBill = approvalBillMapper.getNewApprovalBill(ProcessTypeEnum.SIGNING_PLAN.getKey(), projectId,yearMonth);
            if(null == approvalBill){
                lastYearSigningTargetAmount = BigDecimal.ZERO;
            }else {
                lastYearSigningTargetAmount = getApprovalBillYearSigningTargetAmount(approvalBill);
            }
        }else {
            //当月最新审批单
            ApprovalBill approvalBill = approvalBillMapper.getNewApprovalBill(ProcessTypeEnum.SIGNING_PLAN.getKey(), projectId,yearMonth);
            if(null == approvalBill){
                yearSignTargetAmount = signPlanVersionService.getYearSignTarget(signPlanVersionList.stream().map(s -> s.getId()).collect(Collectors.toList()), yearMonth, 1);
                lastYearSigningTargetAmount = BigDecimal.ZERO;
            }else {
                yearSignTargetAmount = getApprovalBillYearSigningTargetAmount(approvalBill);
                //上个审批单
                ApprovalBill lastResApprovalBill = approvalBillMapper.getLastApprovalBill(approvalBill);
                if(null == lastResApprovalBill){
                    lastYearSigningTargetAmount = BigDecimal.ZERO;
                }else {
                    lastYearSigningTargetAmount = getApprovalBillYearSigningTargetAmount(lastResApprovalBill);
                }
            }
        }
        differenceAmount = yearSignTargetAmount.subtract(lastYearSigningTargetAmount);

        map.put("yearSignTargetAmount",yearSignTargetAmount);
        map.put("lastYearSigningTargetAmount",lastYearSigningTargetAmount);
        map.put("differenceAmount",differenceAmount);
        return map;
    }

    /**
     * 获取全盘年度签约目标和上一审批单年度签约目标
     * @param signPlanVersionList
     * @return
     */
    private boolean isNotApproved(List<SignPlanVersion> signPlanVersionList) {
        for (SignPlanVersion signPlanVersion : signPlanVersionList){
            if(VersionStatusEnum.NOTPREPARED.getKey().equals(signPlanVersion.getVersionState())
                    || VersionStatusEnum.ORGANIZATION.getKey().equals(signPlanVersion.getVersionState())){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取分期下全盘最新版本
     * @param projectfId
     * @return
     */
    private SignPlanVersion getOverallByProjectf(String projectfId){
        /**
         * 1.分期无战规后签约计划，取投资版、预算版中最新版签约计划；
         * 2.分期一房一价前，取战规版、预算版、月度动态版中最新版签约计划；
         * 3.分期一房一价后，取预算版、月度动态版中最新版签约计划；
         */
        List<String> versionStates = Arrays.asList(VersionStatusEnum.SUCCESSAPPROVED.getKey());
        List<String> beforeWarplanTypes = Arrays.asList(VersionTypeEunm.INVESTMENT.getKey(),VersionTypeEunm.BUDGET.getKey());
        List<String> beforeSaleTypes = Arrays.asList(VersionTypeEunm.WARPLAN.getKey(),VersionTypeEunm.BUDGET.getKey(),VersionTypeEunm.DYNAMIC.getKey());
        List<String> afterSaleTypes = Arrays.asList(VersionTypeEunm.BUDGET.getKey(),VersionTypeEunm.DYNAMIC.getKey());

        //查询分期下一房一价的最新签约版本
        SignPlanVersion signPlanVersion = signPlanVersionMapper.selectContainSale(projectfId,null, VersionStatusEnum.SUCCESSAPPROVED.getKey());
        //是否一房一价
        if(null == signPlanVersion){
            //分期一房一价前
            signPlanVersion = signPlanVersionMapper.selectNewesVersion(projectfId, beforeSaleTypes, versionStates, IsDeleteEnum.NO.getKey());
            //若无战规后版本，取投资版、预算版中最新版签约计划
            if (null == signPlanVersion) {
                signPlanVersion = signPlanVersionMapper.selectNewesVersion(projectfId, beforeWarplanTypes, versionStates,IsDeleteEnum.NO.getKey());
            }
        }else {
            //分期一房一价后
            signPlanVersion = signPlanVersionMapper.selectNewesVersion(projectfId, afterSaleTypes, versionStates, IsDeleteEnum.NO.getKey());
        }
        return signPlanVersion;
    }

    /**
     * 查询审批单的年度签约目标
     * @param approvalBill
     * @return
     */
    BigDecimal getApprovalBillYearSigningTargetAmount(ApprovalBill approvalBill){
        //审批单提交审批时间
        String yearMonth = LocalDateTimeUtils.getLocalMonth(approvalBill.getCreatedTime());
        //审批单全盘签约id列表
        List<String> overallVersionIds = signPlanApprovedMapper.selectByVersionId(approvalBill.getId());
        return signPlanVersionService.getYearSignTarget(overallVersionIds,yearMonth,1);
    }


}
